package utils

import (
	"context"
	"encoding/json"
	"git.myscrm.cn/golang/stark/v4"
	"github.com/parnurzeal/gorequest"
)

type HttpClientTool struct {
	response gorequest.Response
	body     []byte
	errs     []error
}

func New() *HttpClientTool {
	return &HttpClientTool{}
}

const (
	GO_REQUEST_DEBUG  = "go_request_debug"
)

// Post
// http client post request tool
func (s *HttpClientTool) Post(ctx context.Context, url string, params interface{}, headers map[string]string) *HttpClientTool {
	stark.Logger.Infof(ctx, "(http-client-post-before) http request url:%s ,header: %+v, params: %+v", url, headers, params)
	request := gorequest.New()
	reqDebug := stark.Configer.(stark.ApolloConfigerIface).GetStringValue(GO_REQUEST_DEBUG, "0")
	if reqDebug == "1" {
		request.SetDebug(true)
	}

	// default: application/json
	client := request.Post(url).Set("Content-Type", "application/json")

	// custom headers
	if headers != nil {
		for key, val := range headers {
			client.Set(key, val)
		}
	}

	if params != nil {
		client = client.Send(params)
	}

	s.response, s.body, s.errs = client.EndBytes()

	stark.Logger.Infof(ctx, "(http-client-post-after) http request url:%s ,header: %+v, params: %+v, body: %+v, errs: %+v, response: %+v",
		url, headers, params, string(s.body), s.errs, s.response)

	return s
}

// Get
// http client get request tool
func (s *HttpClientTool) Get(ctx context.Context, url string, headers map[string]string) *HttpClientTool {
	stark.Logger.Infof(ctx, "(http-client-get-before) http request url:%s ,header: %+v", url, headers)
	request := gorequest.New()
	reqDebug := stark.Configer.(stark.ApolloConfigerIface).GetStringValue(GO_REQUEST_DEBUG, "0")
	if reqDebug == "1" {
		request.SetDebug(true)
	}
	client := request.Get(url)

	// custom headers
	if headers != nil {
		for key, val := range headers {
			client.Set(key, val)
		}
	}

	s.response, s.body, s.errs = client.EndBytes()

	stark.Logger.Infof(ctx, "(http-client-get-after) http request url:%s ,header: %+v, body: %+v, errs: %+v, response: %+v",
		url, headers, string(s.body), s.errs, s.response)

	return s
}

// EndStruct
// convert interface(v) to struct
func (s *HttpClientTool) EndStruct(v interface{}) (gorequest.Response, []byte, []error) {
	resp, body, errs := s.response, s.body, s.errs
	if errs != nil {
		return nil, body, errs
	}

	err := json.Unmarshal(body, &v)
	if err != nil {
		s.errs = append(s.errs, err)
		return resp, body, s.errs
	}

	return resp, body, nil
}
